﻿using System.Collections.Generic;
using System.Linq;
using MarriageFertility.Helpers;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Encounters;
using TaleWorlds.Core;
using TaleWorlds.InputSystem;
using TaleWorlds.Library;
using TaleWorlds.MountAndBlade;

namespace MarriageFertility.Missions
{
    internal class DuelMultipleMissiionLogic : MissionLogic
    {
        private readonly bool _spawnWithHorses;
        private readonly bool _isInsideSettlement;

        private BasicMissionTimer _battleEndTimer;
        private Agent _playerAgent;
        private List<Agent> _enemyAgents;
        private bool _battleHasEnded;
        private bool _playerWon;
        private bool _isFriendCombat;

        public DuelMultipleMissiionLogic(bool spawnWithHorses, bool isFriendCombat, bool isInsideSettlement)
        {
            _spawnWithHorses = spawnWithHorses;
            _isInsideSettlement = isInsideSettlement;
            _isFriendCombat = isFriendCombat;
            _enemyAgents = new List<Agent>();
        }

        public override void AfterStart()
        {
            SetupMission();
            SetupAgents();
        }

        private void SetupMission()
        {
            
            Mission.SetMissionMode(MissionMode.Battle, true);
            _battleHasEnded = false;
            _battleEndTimer = new BasicMissionTimer();
            InitializeMissionTeams();
        }

        private void SetupAgents()
        {
            (MatrixFrame playerSpawnFrame, MatrixFrame enemySpawnFrame) = _isInsideSettlement
                ? MissionHelper.GetArenaSpawnFrames()
                : MissionHelper.GetBattleSpawnFrames();
            _playerAgent = MissionHelper.SpawnAgent(CharacterObject.PlayerCharacter, playerSpawnFrame, true, _isFriendCombat,
                _spawnWithHorses);

            for (int i = 0; i < DuelManager.DuelEnemies.Count; i++)
            {
                _enemyAgents.Add(MissionHelper.SpawnAgent(DuelManager.DuelEnemies[i], enemySpawnFrame, false, _isFriendCombat,
                    _spawnWithHorses));
            }

            Mission.CameraIsFirstPerson = false;
        }

        public override void OnMissionTick(float dt)
        {
            if (_battleHasEnded && _battleEndTimer.ElapsedTime > 4.0)
            {
                DisplayBattleEndInformation();
                _battleEndTimer.Reset();
            }
        }

        private void DisplayBattleEndInformation()
        {
            var leaveKeyText = Game.Current.GameTextManager.GetHotKeyGameTextFromKeyID(
                HotKeyManager.GetAllCategories()
                    .FirstOrDefault(r => r.GameKeyCategoryId == "Generic")?
                    .RegisteredGameKeys[4].KeyboardKey.ToString());

            GameTexts.SetVariable("leave_key", leaveKeyText.ToString());
            MBInformationManager.AddQuickInformation(GameTexts.FindText(_playerWon ? "str_battle_won" : "str_battle_lost"));
        }

        public override void OnAgentRemoved(Agent affectedAgent, Agent affectorAgent, AgentState agentState,
            KillingBlow killingBlow)
        {
            if (affectedAgent.IsHuman)
            {
                if (affectedAgent == _playerAgent)
                {
                    _playerWon = false;
                    _battleHasEnded = true;
                }
                else
                {
                    _enemyAgents.Remove(affectedAgent);
                    if (_enemyAgents.Count <= 0)
                    {
                        _playerWon = true;
                        _battleHasEnded = true;
                    }
                }
            }
        }

        protected override void OnEndMission()
        {
            DuelManager.SetDuelMissionResult(_playerWon);
            DuelManager.CallBackEndEvent(_playerWon);
            PlayerEncounter.Finish();
        }

        private void InitializeMissionTeams()
        {
            Mission.Teams.Add(BattleSideEnum.Defender, Hero.MainHero.MapFaction.Color, Hero.MainHero.MapFaction.Color2,
                Hero.MainHero.Clan.Banner);

            foreach (var duelEnemy in DuelManager.DuelEnemies)
            {
                Mission.Teams.Add(BattleSideEnum.Attacker, duelEnemy.Culture.Color,
                    duelEnemy.Culture.Color2, duelEnemy.HeroObject?.Clan?.Banner);
            }
            Mission.PlayerTeam = Mission.DefenderTeam;
        }
    }
}